package com.api.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.api.dispose.base.BaseDispose;
import com.api.dispose.base.DesDispose;
import com.api.entity.Api;
import com.api.entity.Domain;
import com.api.entity.Module;
import com.api.entity.Project;
import com.api.entity.RequestHeader;
import com.api.entity.RequestParams;
import com.api.entity.ResponseParams;
import com.api.service.ApiService;
import com.api.service.ModuleService;
import com.api.service.ProjectService;
import com.api.service.RequestHeaderService;
import com.api.service.RequestParamsService;
import com.api.service.ResponseParamsService;
import com.api.util.ApiJson;
import com.api.util.ApiUtil;
import com.api.util.ArrayUtil;
import com.api.util.FormatUtil;
import com.api.util.HttpJson;

@Controller
@RequestMapping("/api")
public class ApiController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(ApiController.class);

	@Autowired
	private ApiService apiService;
	@Autowired
	private ModuleService moduleService;
	@Autowired
	private ProjectService projectService;
	@Autowired
	private com.api.service.DomainService DomainService;
	@Autowired
	private ResponseParamsService responseParamsService;
	@Autowired
	private RequestParamsService requestParamsService;
	@Autowired
	private RequestHeaderService requestHeaderService;

	public Object lock = new Object();

	@RequestMapping("/index")
	public String index(Model model, String apiId) {
		Api apiInfo = apiService.get(apiId);
		Module moduleInfo = moduleService.getModuleById(apiInfo.getModuleId());
		Project projectInfo = projectService.getProjectById(moduleInfo.getProjectId());
		model.addAttribute("apiInfo", apiInfo);
		model.addAttribute("moduleInfo", moduleInfo);
		model.addAttribute("projectInfo", projectInfo);

		List<Domain> domainList = DomainService.getDomainList(moduleInfo.getProjectId());

		Domain damainDef = new Domain();
		damainDef.setIpOrDomain(apiInfo.getIp());
		damainDef.setPort(apiInfo.getPort());
		damainDef.setProjectId(projectInfo.getId());
		damainDef.setName("默认");
		damainDef.setId("-1");
		if (domainList == null) {
			domainList = new ArrayList<Domain>();
		}
		domainList.add(0, damainDef);
		model.addAttribute("domainList", domainList);

		String api_id = apiInfo.getId();

		List<RequestParams> requestParamsList = requestParamsService.getRequestParamsList(api_id);
		List<ResponseParams> responseParamsList = responseParamsService.getResponseParamsList(api_id);
		List<RequestHeader> requestHeaderList = requestHeaderService.getRequestHeaderList(api_id);

		model.addAttribute("requestParamsList", requestParamsList);
		if (requestParamsList != null && requestParamsList.size() > 0) {
			String requestParamsListIds = "";
			for (int i = 0; i < requestParamsList.size(); i++) {
				if (StringUtils.isNotEmpty(requestParamsListIds)) {
					requestParamsListIds = requestParamsListIds + "_";
				}
				requestParamsListIds = requestParamsListIds + requestParamsList.get(i).getId().toString();
			}
			model.addAttribute("requestParamsListIds", requestParamsListIds);
		}

		model.addAttribute("requestHeaderList", requestHeaderList);
		if (requestHeaderList != null && requestHeaderList.size() > 0) {
			String requestHeaderListIds = "";
			for (int i = 0; i < requestHeaderList.size(); i++) {
				if (StringUtils.isNotEmpty(requestHeaderListIds)) {
					requestHeaderListIds = requestHeaderListIds + "_";
				}
				requestHeaderListIds = requestHeaderListIds + requestHeaderList.get(i).getId().toString();
			}
			model.addAttribute("requestHeaderListIds", requestHeaderListIds);
		}

		model.addAttribute("responseParamsList", responseParamsList);
		if (responseParamsList != null && responseParamsList.size() > 0) {
			String responseParamsListIds = "";
			for (int i = 0; i < responseParamsList.size(); i++) {
				if (StringUtils.isNotEmpty(responseParamsListIds)) {
					responseParamsListIds = responseParamsListIds + "_";
				}
				responseParamsListIds = responseParamsListIds + responseParamsList.get(i).getId().toString();
			}
			model.addAttribute("responseParamsListIds", responseParamsListIds);
		}
		return "api/index";
	}

	@RequestMapping("/doRequest")
	@ResponseBody
	public ApiJson doRequest(HttpServletRequest req) {
		ApiJson json = new ApiJson();
		String allUrl = ApiUtil.getAllUrl(req);
		// 参数验证
		if (!ApiUtil.isBank_allUrl(req)) {
			json.setIsSuccess(false);
			json.setMessage("ip url 不能为空");
			return json;
		}
		BaseDispose baseDispose = getDispose(req);
		Map<String, String> queryParas = baseDispose.disposeRequest(getManagerApi_requestParams(req));
		HttpJson httpJson = ApiUtil.httpRequest(allUrl, queryParas, req.getParameter("requestMethod"), getManagerApi_requestHeader(req));
		if (!httpJson.getIsSuccess()) {
			json.setIsSuccess(false);
			json.setMessage("错误信息是：" + httpJson.getData());
			return json;
		}
		// 处理返回值
		String responseStr = baseDispose.disposeResponse(httpJson.getData());
		json.setData(responseStr);
		json.setIsSuccess(true);
		json.setMessage("请求成功");

		return json;
	}

	@RequestMapping("/doBatchRequest")
	@ResponseBody
	public ApiJson doBatchRequest(HttpServletRequest req,HttpSession session) {
		final ApiJson json = new ApiJson();
		final String allUrl = ApiUtil.getAllUrl(req);
		// 参数验证
		if (!ApiUtil.isBank_allUrl(req)) {
			json.setIsSuccess(false);
			json.setMessage("ip url 不能为空");
			return json;
		}
		final BaseDispose baseDispose = getDispose(req);
		final Map<String, String> queryParas = baseDispose.disposeRequest(getManagerApi_requestParams(req));
		final String requestMethod = req.getParameter("requestmethod");
		ArrayUtil.remove(req.getParameter("apiId"));
		int threadNum = Integer.parseInt(req.getParameter("threadNum"));
		final CountDownLatch latch = new CountDownLatch(threadNum);
		final int requestNum = Integer.parseInt(req.getParameter("requestNum"));
		for (int i = 0; i < threadNum; i++) {
			new Thread(new Runnable() {
				public void run() {
					for (int j = 0; j < requestNum; j++) {
						HttpJson httpJson = ApiUtil.httpRequest(allUrl, queryParas, requestMethod, getManagerApi_requestHeader(req));
						if (!httpJson.getIsSuccess()) {
							json.setIsSuccess(false);
							json.setMessage("错误信息是：" + httpJson.getData());
							return;
						}
						// 处理返回值
						String responseStr = baseDispose.disposeResponse(httpJson.getData());
						// synchronized (lock) {
						List<String> list = ArrayUtil.get(req.getParameter("apiId"));
						if (list == null) {
							list = new ArrayList<String>();
						}
						list.add(responseStr);
						ArrayUtil.put(req.getParameter("apiId"), list);
						// }
						logger.info("线程"+Thread.currentThread()+"的第"+j+1+"次请求完毕");
					}
					latch.countDown();
				}
			}).start();
		}
		try {
			latch.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
			logger.error("批处理 线程{CountDownLatch } 报异常" + e);
		}
		logger.info("-------所有请求完毕------------");
		List<String> list = ArrayUtil.get(req.getParameter("apiId"));

		json.setData(JSONObject.toJSON(list));
		json.setIsSuccess(true);
		json.setMessage("请求成功");
		return json;
	}

	private BaseDispose getDispose(HttpServletRequest req) {
		BaseDispose baseDispose;
		if ("base".equals(req.getParameter("disposeType"))) {
			baseDispose = new BaseDispose();
		} else if ("des".equals(req.getParameter("disposeType"))) {
			baseDispose = new DesDispose();
		} else {
			baseDispose = new BaseDispose();
		}
		return baseDispose;
	}

	@RequestMapping("/saveApiInfo")
	@ResponseBody
	public ApiJson saveApiInfo(Api api, HttpServletRequest req) {
		// 存储api数据
		ApiJson jsonApi = new ApiJson();
		jsonApi.setMessage("保存成功");
		jsonApi.setIsSuccess(true);
		if (api.getId() == null) {
			apiService.add(api);
		} else {
			apiService.update(api);
		}
		// 暴力 删除数据库 RequestParams 数据
		String api_Id = api.getId();
		if (api.getId() != null) {
			requestHeaderService.delete(api_Id);
			responseParamsService.delete(api_Id);
			requestParamsService.delete(api_Id);
		}
		// 存储requestHeader
		List<RequestHeader> requestHeaderList = getManagerApi_requestHeader(req);
		if (requestHeaderList != null && requestHeaderList.size() > 0) {
			for (int i = 0; i < requestHeaderList.size(); i++) {
				RequestHeader requestheader = requestHeaderList.get(i);
				if (api.getId() != null) {
					requestheader.setApi_id(api.getId());
				}
				requestHeaderService.add(requestheader);
				;
			}
		}
		// 存储RequestParams
		List<RequestParams> RequestParamsList = getManagerApi_requestParams(req);
		if (RequestParamsList != null && RequestParamsList.size() > 0) {
			for (int i = 0; i < RequestParamsList.size(); i++) {
				RequestParams requestParams = RequestParamsList.get(i);
				if (api.getId() != null) {
					requestParams.setApi_id(api.getId());
				}
				requestParamsService.add(requestParams);
				;
			}
		}
		// 存储ResponseParams
		List<ResponseParams> ResponseParamsList = getManagerApi_responseParams(req);
		if (ResponseParamsList != null && ResponseParamsList.size() > 0) {
			for (int i = 0; i < ResponseParamsList.size(); i++) {
				ResponseParams responseParams = ResponseParamsList.get(i);
				if (api.getId() != null) {
					responseParams.setApi_id(api.getId());
				}
				responseParamsService.add(responseParams);
			}
		}
		return jsonApi;
	}

	@RequestMapping("/formatStr")
	@ResponseBody
	public ApiJson formatStr(String data) {
		ApiJson json = new ApiJson();
		json.setMessage("格式化成功");
		if (StringUtils.isNotEmpty(data)) {
			String newData = StringEscapeUtils.unescapeHtml4(data);
			json.setData(FormatUtil.formatJson(newData));
		} else {
			json.setIsSuccess(false);
		}
		return json;
	}

	@RequestMapping("/saveOrEdit")
	public String saveOrEdit(Model model, String project_id, String api_id) {
		List<Module> list = moduleService.getModuleByProjectId(project_id);
		if (list != null && list.size() > 0) {
			model.addAttribute("moduleList", list);
		}
		model.addAttribute("apiInfo", new Api());
		if (StringUtils.isNotEmpty(api_id)) {
			Api apiInfo = apiService.get(api_id);
			if (apiInfo != null) {
				model.addAttribute("apiInfo", apiInfo);
			}

		}
		return "api/saveOrEdit";
	}

	@RequestMapping("/doSaveOrEdit")
	@ResponseBody
	public ApiJson doSaveOrEdit(Model model, Api api) {
		ApiJson apiJson = new ApiJson();
		apiJson.setMessage("请求成功");
		if (StringUtils.isNotEmpty(api.getId())) {
			apiService.update(api);
		} else {
			api.setStatus(1);
			apiService.add(api);
		}
		return apiJson;
	}

	@RequestMapping("/deleteApi")
	@ResponseBody
	public ApiJson deleteApi(String api_id) {
		ApiJson apiJson = new ApiJson();
		if (StringUtils.isEmpty("api_id")) {
			apiJson.setMessage("id不能为空");
			apiJson.setIsSuccess(false);
			return apiJson;
		}
		Api api = apiService.get(api_id);
		if (api != null) {
			api.setStatus(0);
			apiService.update(api);
		}
		apiJson.setMessage("删除成功");
		apiJson.setIsSuccess(true);
		return apiJson;
	}
}
